﻿/****************************** Module Header ******************************\
 * Module Name:  MessageBoxTimeout.cs
 * Module Version:  1.0.0 (2012-4-28)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is a basic class for the webpage.  It supplies common public
 * methods to process a internet request, such as Request processing and so on. 
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace UCF.Core.Forms
{
    /// <summary>
    /// 定时关闭的MessageBox对象
    /// </summary>
    public class MessageBoxTimeout
    {

        [DllImport("kernel32.dll")]
        private static extern uint GetCurrentThreadId();

        private delegate int EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

        [DllImport("user32.dll")]
        private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        [DllImport("user32.dll")]
        private static extern int GetClassName(IntPtr hWnd, [Out] StringBuilder lpClassName, int nMaxCount);

        [DllImport("user32.dll")]
        private static extern bool IsWindowEnabled(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        /// <summary>
        /// 定时器线程类
        /// </summary>
        private class TimerThread
        {
            private readonly DateTime timeoutTime;
            private readonly uint currentThreadId;
            private bool terminateFlag;
            private readonly Thread thread;

            /// <summary>
            /// 构造方法
            /// </summary>
            /// <param name="timeoutMillisec"></param>
            public TimerThread(int timeoutMillisec)
            {
                timeoutTime = DateTime.Now.AddMilliseconds(timeoutMillisec);
                currentThreadId = GetCurrentThreadId();
                terminateFlag = false;
                thread = new Thread(ThreadProc); thread.Start();
            }
            private void ThreadProc()
            {
                while (!terminateFlag)
                {
                    Thread.Sleep(100);
                    if (DateTime.Now > timeoutTime)
                    {
                        EnumWindows(EnumWindowsProc, new IntPtr(0)); return;
                    }
                }
            }

            private int EnumWindowsProc(IntPtr hWnd, IntPtr lParam)
            {
                uint processId; uint threadId; threadId = GetWindowThreadProcessId(hWnd, out processId);
                if (threadId == currentThreadId)
                {
                    StringBuilder className = new StringBuilder("", 256);
                    GetClassName(hWnd, className, 256); if (className.ToString() == "#32770" && IsWindowEnabled(hWnd))
                    {
                        const int WM_COMMAND = 0x111; PostMessage(hWnd, WM_COMMAND, new IntPtr(2), new IntPtr(0)); return 0;
                    }
                } return 1;
            }
            public void Terminate()
            {
                terminateFlag = true; thread.Join();
            }
        }

        /// <summary>
        /// 弹出定时关闭的消息框
        /// </summary>
        /// <param name="text"></param>
        /// <param name="timeoutMillsec"></param>
        /// <returns></returns>
        public static DialogResult Show(string text, int timeoutMillsec)
        {
            TimerThread tt = new TimerThread(timeoutMillsec); try
            {
                return MessageBox.Show(text);
            }
            finally { tt.Terminate(); }
        }

        /// <summary>
        /// 弹出定时关闭的消息框
        /// </summary>
        /// <param name="text"></param>
        /// <param name="caption"></param>
        /// <param name="timeoutMillsec"></param>
        /// <returns></returns>
        public static DialogResult Show(string text, string caption, int timeoutMillsec)
        {
            TimerThread tt = new TimerThread(timeoutMillsec); try { return MessageBox.Show(text, caption); }
            finally
            {
                tt.Terminate();
            }
        }

        /// <summary>
        /// 弹出定时关闭的消息框
        /// </summary>
        /// <param name="text"></param>
        /// <param name="caption"></param>
        /// <param name="buttons"></param>
        /// <param name="timeoutMillsec"></param>
        /// <returns></returns>
        public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, int timeoutMillsec)
        {
            TimerThread tt = new TimerThread(timeoutMillsec); try { return MessageBox.Show(text, caption, buttons); }
            finally { tt.Terminate(); }
        }

        /// <summary>
        /// 弹出定时关闭的消息框
        /// </summary>
        /// <param name="text"></param>
        /// <param name="caption"></param>
        /// <param name="buttons"></param>
        /// <param name="icon"></param>
        /// <param name="timeoutMillsec"></param>
        /// <returns></returns>
        public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, int timeoutMillsec)
        {
            TimerThread tt = new TimerThread(timeoutMillsec); try
            {
                return MessageBox.Show(text, caption, buttons, icon);
            }
            finally { tt.Terminate(); }
        }

        /// <summary>
        /// 弹出定时关闭的消息框
        /// </summary>
        /// <param name="text"></param>
        /// <param name="caption"></param>
        /// <param name="buttons"></param>
        /// <param name="icon"></param>
        /// <param name="defaultButton"></param>
        /// <param name="timeoutMillsec"></param>
        /// <returns></returns>
        public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, int timeoutMillsec)
        {
            TimerThread tt = new TimerThread(timeoutMillsec); try
            {
                return MessageBox.Show(text, caption, buttons, icon, defaultButton);
            }
            finally { tt.Terminate(); }
        }

        /// <summary>
        /// 弹出定时关闭的消息框
        /// </summary>
        /// <param name="text"></param>
        /// <param name="caption"></param>
        /// <param name="buttons"></param>
        /// <param name="icon"></param>
        /// <param name="defaultButton"></param>
        /// <param name="options"></param>
        /// <param name="timeoutMillsec"></param>
        /// <returns></returns>
        public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, MessageBoxOptions options, int timeoutMillsec)
        {
            TimerThread tt = new TimerThread(timeoutMillsec); try { return MessageBox.Show(text, caption, buttons, icon, defaultButton, options); }
            finally { tt.Terminate(); }
        }
    }
}